﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;

namespace myMapObj
{
    public class SEGM
    {
        #region 字段
        private string _filepath;//SEGM储存路径       
        private moLayers _map = null;//地图文件
        private moCoordinates _Geocoordinate;//地理坐标系
        private moCoordinates _Procoordinate;//投影坐标系
        private double _MinX, _MaxX;//空间数据所占空间范围的X方向最小、最大值
        private double _MinY, _MaxY;//空间数据所占空间范围的Y方向最小、最大值
        private double _scale = 1;//比例尺
        #endregion

        #region 属性
        internal moCoordinates GeoCoordinate { get { return _Geocoordinate; } set { _Geocoordinate = value; } }//地理坐标系
        internal moCoordinates ProCoordinate { get { return _Procoordinate; } set { _Procoordinate = value; } }//投影坐标系
        public string FilePath { get { return _filepath; } set { _filepath = value; } } //储存路径
        public moLayers MyMap { get { return _map; } set { _map = value; } }//地图文件
        internal double MinX { get { return _MinX; } set { _MinX = value; } }
        internal double MaxX { get { return _MaxX; } set { _MaxX = value; } }
        internal double MinY { get { return _MinY; } set { _MinY = value; } }
        internal double MaxY { get { return _MaxY; } set { _MaxY = value; } }
        internal double Scale { get { return _scale; } set { _scale = value; } }
        #endregion

        #region 构造函数
        public SEGM(string path)
        {
            if (Path.GetExtension(path) != ".segm")
                throw new IOException("文件拓展名不正确！");
            _filepath = path;
            Open();
        }
        
        internal SEGM(moLayers newmap, double minX, double maxX, double minY, double maxY, double scale)
        {
            _map = newmap;

            _MinX = minX;
            _MaxX = maxX;
            _MinY = minY;
            _MaxY = maxY;
            
            _scale = scale;
        }

        #endregion

        #region 函数

        public void Open()
        {
            FileStream fs = new FileStream(_filepath, FileMode.Open,FileAccess.Read, FileShare.ReadWrite);
            StreamReader sr = new StreamReader(fs);
            string line = sr.ReadLine();
            string[] words = line.Split(' ');
            _Geocoordinate = moCoordinates.WGS1984;//由于不存在null选项
            _Procoordinate = moCoordinates.WGS1984;//由于不存在null选项
            //记录地理坐标系
            switch (words[1])
            {
                case "WGS1984":
                    _Geocoordinate = moCoordinates.WGS1984;
                    break;
            }
            //记录投影坐标系
            switch (words[2])
            {
                case "WGS1984":
                    _Geocoordinate = moCoordinates.WGS1984;
                    break;
            }
            //生成地图
            _map = new moLayers(words[0], _Geocoordinate, Convert.ToDouble(words[3]));
            _scale = Convert.ToDouble(words[3]);
            //地图最大最小坐标读取

            _MinX = Convert.ToDouble(words[4]); 
            _MaxX = Convert.ToDouble(words[5]);
            _MinY = Convert.ToDouble(words[6]);
            _MaxY = Convert.ToDouble(words[7]);

            //图层数量
            int layercount = Convert.ToInt32(words[8]);

            for (int i = 0; i < layercount; i++)
            {
                string layerpath = sr.ReadLine();

                moMapLayer newlayer = null;
                if (Path.GetExtension(layerpath) == ".shp")
                {
                    //TODO先只可读SHP
                    Shapefile newshp = new Shapefile(layerpath);
                    newlayer = new moMapLayer(newshp);
                }
                else
                {
                    SEGV newsegv = new SEGV(layerpath);
                    newlayer = new moMapLayer(newsegv);
                }
                newlayer.FilePath = layerpath;
                //设置是否可见
                string visible = sr.ReadLine();
                if (visible == "True")
                    newlayer.Visible = true;
                else
                    newlayer.Visible = false;

                //获取渲染方式 
                string layerline = sr.ReadLine();                
                string newrendertyppe = layerline.Split(' ')[0];

                switch (newrendertyppe)
                {
                    //唯一值渲染
                    case "UniqueValueRenderer":

                        string field_uvr = layerline.Split(' ')[1];

                        moUniqueValueRenderer sRenderer = new moUniqueValueRenderer();
                        sRenderer.Field = field_uvr;

                        List<string> sValues = new List<string>();
                        Int32 sFeatureCount = newlayer.Features.Count;
                        for (Int32 j = 0; j <= sFeatureCount - 1; j++)
                        {
                            string sValue = (string)newlayer.Features.GetItem(j).Attributes.GetItem(0);
                            sValues.Add(sValue);
                        }
                        //去除重复
                        sValues = sValues.Distinct().ToList();
                        //生成符号
                        Int32 sValueCount = sValues.Count;
                        for (Int32 j = 0; j <= sValueCount - 1; j++)
                        {
                            moSimpleFillSymbol sSymbol = new moSimpleFillSymbol();
                            sRenderer.AddUniqueValue(sValues[j], sSymbol);
                        }
                        sRenderer.DefaultSymbol = new moSimpleFillSymbol();
                        newlayer.Renderer = sRenderer;
                        break;
                                              
                    //分级渲染
                    case "ClassBreaksRenderer":
                        string field_cbr = layerline.Split(' ')[1];
                        moClassBreaksRenderer sBRenderer = new moClassBreaksRenderer();
                        sBRenderer.Field = field_cbr;

                        List<double> sBValues = new List<double>();
                        Int32 sBFeatureCount = newlayer.Features.Count;
                        Int32 sFieldIndex = newlayer.AttributeFields.FindField(sBRenderer.Field);
                        //读出所有值
                        for (Int32 j = 0; j <= sBFeatureCount - 1; j++)
                        {
                            double sBValue = (float)newlayer.Features.GetItem(j).Attributes.GetItem(sFieldIndex);
                            sBValues.Add(sBValue);
                        }
                        //获取最小最大值，并分五级
                        double sMinValue = sBValues.Min();
                        double sMaxValue = sBValues.Max();
                        for (Int32 j = 0; j <= 4; j++)
                        {
                            double sValue = sMinValue + (sMaxValue - sMinValue) * (j + 1) / 5;
                            moSimpleFillSymbol sSymbol = new moSimpleFillSymbol();
                            sBRenderer.AddBreakValue(sValue, sSymbol);
                        }
                        Color sStartColor = Color.FromArgb(255, 255, 192, 192);
                        Color sEndColor = Color.Maroon;
                        sBRenderer.RampColor(sStartColor, sEndColor);
                        sBRenderer.DefaultSymbol = new moSimpleFillSymbol();
                        newlayer.Renderer = sBRenderer;
                        break;
                    //简单渲染
                    default:
                        newlayer.Renderer = new moSimpleRenderer();
                        break;

                }

                //判断是否有注记信息
                string hastext = sr.ReadLine();
                if (hastext == "True")
                {
                    newlayer.HasText = true;
                    moLabelRenderer sLabelRenderer = new moLabelRenderer();
                    //Int32 sFieldIndex = newlayer.AttributeFields.FindField(sr.ReadLine());
                    sLabelRenderer.Field = sr.ReadLine();
                    Font sOldFont = sLabelRenderer.TextSymbol.Font;
                    sLabelRenderer.TextSymbol.Font = new Font(sOldFont.Name, 12);
                    sLabelRenderer.TextSymbol.UseMask = true;
                    sLabelRenderer.LabelFeatures = true;
                    newlayer.LabelRenderer = sLabelRenderer;                   
                }
                else
                    newlayer.HasText = false;

                _map.Add(newlayer);
            }
            fs.Dispose();
            sr.Dispose();

        }

        public void Save(string save_path)
        {
            _filepath = save_path;
            FileStream fs = new FileStream(_filepath, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);

            string line = _map.MapName + " " + _Geocoordinate.ToString() + " " + _Procoordinate.ToString() + " "
                            + _scale.ToString("F2") + " " + _MinX.ToString("F6") + " " + _MaxX.ToString("F6") + " " + _MinY.ToString("F6") + " " + _MaxY.ToString("F6") + " " + _map.Count.ToString();
            sw.WriteLine(line);
            //对每一图层
            for (int i = 0; i < _map.Count; i++)
            {
                sw.WriteLine(_map.Layers[i].FilePath);
                sw.WriteLine(_map.Layers[i].Visible.ToString());

                switch (_map.Layers[i].Renderer.RendererType)
                {
                    //唯一值渲染
                    case moRendererTypeConstant.UniqueValue:
                        moUniqueValueRenderer Urenderer = (moUniqueValueRenderer)_map.Layers[i].Renderer;
                        string filename_uvr = "UniqueValueRenderer" + " " + Urenderer.Field;
                        sw.WriteLine(filename_uvr);
                        break;

                    //分级渲染
                    case moRendererTypeConstant.ClassBreaks:
                        moClassBreaksRenderer Crenderer = (moClassBreaksRenderer)_map.Layers[i].Renderer;
                        string filename_cbr = "ClassBreaksRenderer" + " " + Crenderer.Field;
                        sw.WriteLine(filename_cbr);
                        break;
                    //简单渲染
                    default:
                        sw.WriteLine(_map.Layers[i].Renderer.ToString());
                        break;

                }

                //判断是否有注记信息
                bool hastext = _map.Layers[i].HasText;
                sw.WriteLine(hastext.ToString());
                if (hastext == true)
                {
                    sw.WriteLine(_map.Layers[i].LabelRenderer.Field);                        
                }

            }
            sw.Close();
            fs.Close();
        }

        /// <summary>
        /// 在指定路径下创建指定类型的空白SEGV文件
        /// </summary>
        /// <param name="path">文件路径</param>
        public static void CreateEmptyCgv(string path)
        {
            SEGM EmptySEGM = new SEGM(new moLayers(), 1, 1, 1, 1, 1);
            EmptySEGM.GeoCoordinate = moCoordinates.None;
            EmptySEGM.ProCoordinate = moCoordinates.None;
            EmptySEGM.Save(path);
        }
        #endregion
    }
}
